
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Main.GamePlay;


namespace Main
{

    public class Main : Microsoft.Xna.Framework.Game
    {
        #region Fields

        public static MouseState CurrentMouseState;
        public static MouseState LastMouseState;

        List<GameplayObject> gameObjects = new List<GameplayObject>();
        List<GameplayObject> currentGameObjects = new List<GameplayObject>();


        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        TimeSpan PlayerSpawnTimer;

        SpriteFont arial;

        public GuideLine line1;
        public GuideLine line2;
        public GuideLine line3;
        public GuideLine line4;

        float spawnPlayerSeconds;
        int FleetSize;

        #endregion

        #region Methods

        public Main()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            IsMouseVisible = true;
            Window.Title = "Atlantis Reverse";
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 750;

            IsFixedTimeStep = false;

        }

        protected override void Initialize()
        {
            base.Initialize();

            spawnPlayerSeconds = 5;
            PlayerSpawnTimer = TimeSpan.FromSeconds(spawnPlayerSeconds);

            FleetSize = 5;

            addedObjects.Clear();
        }// Initialize the game

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            Fleet.shipTexture = Content.Load<Texture2D>("Sprites/ship1");
            GuideLine.LineTexture = Content.Load<Texture2D>("Sprites/GuideLine");

            arial = Content.Load<SpriteFont>("Fonts/arial");

            line1 = new GuideLine();
            line1.Position = new Vector2(0, Window.ClientBounds.Height / 5);
            gameObjects.Add(line1);

            line2 = new GuideLine();
            line2.Position = new Vector2(0, (Window.ClientBounds.Height / 5) * 2);
            gameObjects.Add(line2);

            line3 = new GuideLine();
            line3.Position = new Vector2(0, (Window.ClientBounds.Height / 5) * 3);
            gameObjects.Add(line3);

            line4 = new GuideLine();
            line4.Position = new Vector2(0, (Window.ClientBounds.Height / 5) * 4);
            gameObjects.Add(line4);

        }// Load's game content

        protected override void UnloadContent()
        {

        }// Unload's game content

        protected override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            LastMouseState = CurrentMouseState;
            CurrentMouseState = Mouse.GetState();

            foreach (GameplayObject gameObject in addedObjects)
                gameObjects.Add(gameObject);

            if (FleetSize > 0)
            {
                PlayerSpawnTimer = PlayerSpawnTimer.Subtract(gameTime.ElapsedGameTime);
                if (PlayerSpawnTimer.TotalSeconds <= 0)
                {
                    SpawnPlayer();
                    FleetSize--;
                }
            }
            addedObjects.Clear();
            currentGameObjects.Clear();

            foreach (GameplayObject gameObject in gameObjects)
                currentGameObjects.Add(gameObject);

            foreach (GameplayObject gO in currentGameObjects)
            {
                gO.Window = Window;
            }

            for (int i = 0; i < currentGameObjects.Count; i++)
            {
                if (currentGameObjects[i].Status == ObjectStatus.Dead)
                    gameObjects.Remove(currentGameObjects[i]);
                else
                    currentGameObjects[i].Update(gameTime);
            }

            HandleInput();
        }// Update's the game every frame

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.White);
            spriteBatch.Begin();

            for (int i = 0; i < gameObjects.Count; i++)
                gameObjects[i].Draw(gameTime, spriteBatch);

            spriteBatch.DrawString(arial, "Fleet Size: " + FleetSize, new Vector2(10, 10), Color.Red);

            spriteBatch.End();

            base.Draw(gameTime);
        }// Draw control

        #endregion

        private void SpawnPlayer()
        {
            gameObjects.Add(Fleet.GenerateShip(GraphicsDevice.Viewport, line1.Position, line2.Position, line3.Position, line4.Position));

            spawnPlayerSeconds--;
            if (spawnPlayerSeconds == 0)
            {
                spawnPlayerSeconds = 3;
                gameObjects.Add(Fleet.GenerateShip(GraphicsDevice.Viewport, line1.Position, line2.Position, line3.Position, line4.Position));
            }

            PlayerSpawnTimer = TimeSpan.FromSeconds(spawnPlayerSeconds);


        }// handle ship spawn, every 3 seconds spawn a ship

        public static List<GameplayObject> addedObjects = new List<GameplayObject>();
        public static void Add(GameplayObject newGameObject)
        {
            addedObjects.Add(newGameObject);
        }// list used to add object in GameObject list

        private void CheckCollision()
        {
            for (int i = 0; i < gameObjects.Count; i++)
            {
                for (int j = i + 1; j < gameObjects.Count; j++)
                {
                    if ((gameObjects[i].ColisionRect.Intersects(gameObjects[j].ColisionRect))
                        && (gameObjects[i].Status == ObjectStatus.Active) && (gameObjects[j].Status == ObjectStatus.Active))
                        gameObjects[i].CollisionTRGT(gameObjects[j]);
                }
            }
        }// check collision of all objects

        public void HandleInput()
        {
            bool shipSelected = false;
            bool lineSelected = false;

            for (int i = 0; i < currentGameObjects.Count; i++)//para todos os objetos de jogo
            {
                Fleet f = new Fleet();
                GuideLine gL = new GuideLine();

                //if (currentGameObjects[i] is Fleet && currentGameObjects[i] != null)//se aquele objeto for uma nave
                if (currentGameObjects[i] is Fleet)//se aquele objeto for uma nave
                {

                    f = currentGameObjects[i] as Fleet;//apenas pra pegar a nave no for           

                    //me faz selecionar a nave uma vez que clique nela
                    if (!f.Selected && f.MouseOverSprite && CurrentMouseState.LeftButton == ButtonState.Pressed && LastMouseState.LeftButton != ButtonState.Pressed)
                    {
                        f.Selected = true;
                    }

                    //caso eu clique no campo eu deseleciono a nave atual, ou se eu clicar em outra nave seleciono esta e deseleciono a anterior
                    //else if (f.MouseOverSprite == false && gL.MouseOverSprite == false && CurrentMouseState.LeftButton == ButtonState.Pressed && LastMouseState.LeftButton != ButtonState.Pressed)
                    else if (f.MouseOverSprite == false && !lineSelected && CurrentMouseState.LeftButton == ButtonState.Pressed && LastMouseState.LeftButton != ButtonState.Pressed)
                    {
                        f.Selected = false;
                    }

                    if (f.Selected)
                    {
                        shipSelected = true;
                    }

                }

                if (currentGameObjects[i] is GuideLine && currentGameObjects[i] != null)
                {
                    gL = currentGameObjects[i] as GuideLine;

                    if (!gL.Selected && gL.MouseOverSprite)
                    {
                        gL.Selected = true;
                    }
                    else if (!gL.MouseOverSprite)
                    {
                        gL.Selected = false;
                    }

                    if (gL.Selected)
                    {
                        lineSelected = true;
                    }
                }

                if( (f!=null) && (gL!=null) )
                if (shipSelected && lineSelected && CurrentMouseState.LeftButton == ButtonState.Pressed && LastMouseState.LeftButton != ButtonState.Pressed)
                {
                    f.Position = new Vector2(f.Position.X, gL.Position.Y - (f.Texture.Height / 2));
                }

            }


            //se eu tiver uma nave selecionada, faz tb aparecer as linhas
            if (shipSelected)
            {
                line1.Visible = true;
                line2.Visible = true;
                line3.Visible = true;
                line4.Visible = true;
            }
            else//caso nenhuma nave esteja selecionada, desaparecem as linhas tb
            {
                line1.Visible = false;
                line2.Visible = false;
                line3.Visible = false;
                line4.Visible = false;
            }

        }// Handle player input

    }//Main

}